/*
 * DesktopOCR.java
 *
 * Created on Sep 12, 2011, 5:45:32 PM
 */

package ocr.desktop;

import java.awt.Image;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import ocr.service.OpticalCharacterRecognizer;
import ocr.service.Trainer;
import ocr.system.ImageRetriever;
import ocr.system.InvalidImageException;

/**
 * Run the OCR program for the desktop user.
 *
 * @author Devin
 */
public class DesktopOCR extends javax.swing.JFrame
{
   /**
    * Indicates where the JFileChooser should begin
    */
   private File mStart;
   
    /** Creates new form DesktopOCR */
    public DesktopOCR()
    {
        initComponents();
        mStart = new File(".\\src\\res");
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
   @SuppressWarnings("unchecked")
   // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
   private void initComponents() {

      mOcrButton = new javax.swing.JButton();
      mTrainButton = new javax.swing.JButton();
      jScrollPane2 = new javax.swing.JScrollPane();
      jScrollPane1 = new javax.swing.JScrollPane();
      mTextArea = new javax.swing.JTextArea();
      jLabel1 = new javax.swing.JLabel();

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

      mOcrButton.setText("OCR");
      mOcrButton.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            mOcrButtonActionPerformed(evt);
         }
      });

      mTrainButton.setText("Train");
      mTrainButton.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            mTrainButtonActionPerformed(evt);
         }
      });

      mTextArea.setColumns(20);
      mTextArea.setRows(5);
      jScrollPane1.setViewportView(mTextArea);

      jScrollPane2.setViewportView(jScrollPane1);

      jLabel1.setText("Extracted Text:");

      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
      getContentPane().setLayout(layout);
      layout.setHorizontalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addGap(20, 20, 20)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
               .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE)
               .addGroup(layout.createSequentialGroup()
                  .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 339, Short.MAX_VALUE)
                  .addComponent(mTrainButton)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                  .addComponent(mOcrButton)))
            .addGap(31, 31, 31))
      );
      layout.setVerticalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addGap(26, 26, 26)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
               .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                  .addComponent(mOcrButton)
                  .addComponent(mTrainButton))
               .addComponent(jLabel1))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
            .addContainerGap())
      );

      pack();
   }// </editor-fold>//GEN-END:initComponents

    private void mOcrButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_mOcrButtonActionPerformed
    {//GEN-HEADEREND:event_mOcrButtonActionPerformed
       Image image = retrieveImage();
       try
       {
          mTextArea.setText(OpticalCharacterRecognizer.extractString(image));
          jLabel1.setText("Extracted Text:");
       }
       catch (InvalidImageException e)
       {
          //Display image rejection message to the user
          jLabel1.setText("Error:");
          mTextArea.setText(e.getMessage());
       }
    }//GEN-LAST:event_mOcrButtonActionPerformed

    private void mTrainButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_mTrainButtonActionPerformed
    {//GEN-HEADEREND:event_mTrainButtonActionPerformed
       Image image = retrieveImage();
       try
       {
          mTextArea.setText(new Trainer(new DesktopPrompter(), image).train());
          jLabel1.setText("Training Text:");
       }
       catch (InvalidImageException e)
       {
          //Display image rejection message to the user
          jLabel1.setText("Error:");
          mTextArea.setText(e.getMessage());
       }
    }//GEN-LAST:event_mTrainButtonActionPerformed

    /**
     * Retrieve the image at the file path entered by the user
     *
     * @return The image at the location given by the user
     */
   private Image retrieveImage()
   {
      File image = null;
      JFileChooser chooser = null;
      Image document = null;

      if (mStart.isDirectory())
      {
         chooser = new JFileChooser(mStart);
      }
      else
      {
         chooser = new JFileChooser();
      }

      if (chooser != null)
      {
         chooser.addChoosableFileFilter(new ImageFilter());
         chooser.setAcceptAllFileFilterUsed(false);

         int val = chooser.showOpenDialog(DesktopOCR.this);
         if (val == JFileChooser.APPROVE_OPTION)
         {
            image = chooser.getSelectedFile();
            document = new ImageRetriever(image).readImage();
         }
      }

      return document;
   }

    /**
    * Run the OCR program for the desktop user.
    *
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run() {
                new DesktopOCR().setVisible(true);
            }
        });
    }

   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JLabel jLabel1;
   private javax.swing.JScrollPane jScrollPane1;
   private javax.swing.JScrollPane jScrollPane2;
   private javax.swing.JButton mOcrButton;
   private javax.swing.JTextArea mTextArea;
   private javax.swing.JButton mTrainButton;
   // End of variables declaration//GEN-END:variables

}

/**
 * Defines a image only filter for the JFileChooser
 * 
 * @author Devin
 */
class ImageFilter
   extends FileFilter
{
   /**
    * Defines the conditions for which files or directories should
    * be shown in the JFileChooser.
    *
    * @param f The file to check the conditions for
    * @return true if the file or directory should be displayed
    */
   @Override
   public boolean accept(File f)
   {
      boolean accept = false;
      String extension;
      
      if (f.isDirectory())
      {
         accept = true;
      }

      extension = getExtension(f);

      if (".jpg".equals(extension) ||
          ".png".equals(extension))
      {
         accept = true;
      }

      return accept;
   }

   /**
    * Returns a description for this file filter
    *
    * @return The filter description
    */
   @Override
   public String getDescription()
   {
      return "Image files only";
   }

   /**
    * Returns the file extension of a file.
    *
    * @param f The file to get the extension of
    * @return The file extension
    */
   private String getExtension(File f)
   {
      String extension = null;
      String name = f.getName();

      int i = name.lastIndexOf('.');

      if ((i < name.length()) && (i > 0))
      {
         extension = name.substring(i);
      }
      return extension;
   }
}